#include <stdlib.h>
#include "byte_code.h"
#include "obj.h"


ObjString* objStringCreate(const char* str, int len, HashTable* table) {
    // printf("objStringCreate start\n");
    char* tmp = malloc(len + 1);
    memcpy(tmp, str, len);
    tmp[len] = '\0';
    // printf("tmp len: %d\n", strlen(tmp));
    ObjString* objStr = malloc(sizeof(ObjString));
    Obj obj = {OBJ_STRING};
    objStr->obj = obj;
    objStr->len = len;
    objStr->val = tmp;
    Entry* entry = hashTableGetEntry(table, objStr);
    if(entry != NULL && entry->key != NULL) {
        // printf("objStringCreate end1");
        free(objStr);
        free(tmp);
        return entry->key;
    }
    // printf("objStringCreate end2");
    hashTablePut(table, objStr, NULL);
    return objStr;
}

int strHash(void* key) {
    int res = 0;
    const char* str = (const char*)key;
    int len = strlen(str);
    // printf("strHash len: %d\n", len);
    for (size_t i = 0; i < len; i++)
    {
        res += 31 * res + str[i];
    }
    return res;
}

int objStrHash(void* key) {
    ObjString* objStr = (ObjString*)key;
    // printf("objStrHash %p\n", objStr);
    return strHash(objStr->val);
}

int objStrCompare(void* val1, void* val2) {
    ObjString* v1 = (ObjString*)val1;
    ObjString* v2 = (ObjString*)val2;
    return strcmp(v1->val, v2->val);
}

ObjFunction* objFunctionCreate(const char* str, int len, HashTable* table) {
    ObjFunction* fun = malloc(sizeof(ObjFunction));
    fun->arity = 0;
    chunkInit(&fun->chunk);
    Obj obj = {OBJ_FUNCTION};
    fun->obj = obj;
    fun->name = objStringCreate(str, len, table);
    return fun;
}

void callFrameInit(CallFrame* frame, ObjFunction* fun, int ebp) {
    frame->fun = fun;
    frame->ebp = ebp;
    frame->ip = -1;
}
